package kingwing.dc.core.sevice.quartz.job;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import kingwing.dc.core.model.Infos;
import kingwing.dc.core.model.JobTimeRule;
import kingwing.dc.core.model.Rule;
import kingwing.dc.core.model.RuleDetail;
import kingwing.dc.core.orm.hibernate.CommonHibernateDao;
import kingwing.dc.core.sevice.HTMLProcessor;
import kingwing.dc.core.sevice.JSProcessor;
import kingwing.dc.core.sevice.SinglePageHtmlProcessor;
import kingwing.dc.core.sevice.quartz.dao.JObHibernateDao;
import kingwing.dc.core.view.rule.RulePR;

import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.Restrictions;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.transaction.annotation.Transactional;

import com.bstek.bdf2.core.context.ContextHolder;

import us.codecraft.webmagic.ResultItems;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.pipeline.ResultItemsCollectorPipeline;

/**
 * 这是一个通用的站点采集任务
 * @author Kevin
 * 2017年10月25日
 */
public class JobSite implements Job {

	
	@Resource(name=JObHibernateDao.BEAN_ID)
	private JObHibernateDao jObHibernateDao;
	
	@Resource(name=CommonHibernateDao.BEAN_ID)
	private CommonHibernateDao commonHibernateDao;
	
	@Resource(name="rulePR")
	private RulePR rulePR;
	
	@SuppressWarnings("unchecked")
	@Override
	public void execute(JobExecutionContext context)
			throws JobExecutionException {
		// TODO Auto-generated method stub
		
		JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
		JobTimeRule jobTimeRule = (JobTimeRule)jobDataMap.get("jobTimeRule");
		String keyword =jobDataMap.get("keyword").toString();
		int pages = jobTimeRule.getPages();
		Date date=new Date();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		
		String currentUserName = jobTimeRule.getCreateUserId();
		DetachedCriteria detachedCriteriaRule = DetachedCriteria.forClass(Rule.class);
		Map<String, Object> params = new HashMap<String, Object>();
		detachedCriteriaRule.add(Restrictions.eq("jobTimeRuleID", jobTimeRule.getId()));
		List<Rule> rules = (List<Rule>) this.commonHibernateDao.query(detachedCriteriaRule);
		if (rules==null||rules.isEmpty()) {
			System.out.println(sf.format(date)+":"+currentUserName+"的“"+jobTimeRule.getJobName()+"”任务没有添加站点！");
		}else {
			System.out.println(sf.format(date)+":"+currentUserName+"的“"+jobTimeRule.getJobName()+"”任务开始执行！");
			for (Rule rule : rules) {
				params.put("entity", rule);
				params.put("keyword", keyword);
				params.put("pages", pages);
				this.beginDataCollection(params);
			}
			System.out.println(sf.format(date)+":"+currentUserName+"的“"+jobTimeRule.getJobName()+"”任务执行完成！");
		}
		
	}
	
	/**
	 * 开始采集数据，进行封装
	 * @param params
	 * @return
	 */
	@SuppressWarnings({ "unchecked" })
	@Transactional
	public String beginDataCollection(Map<String, Object> params){
		
		//获取规则集合
		List<Rule> rules = new ArrayList<>();
		String keyword = "";
		int pages = 0;
		if (params != null && !params.isEmpty()) {
			if (params.get("entity") instanceof Rule) {
				rules.add((Rule) params.get("entity"));
			}else {
				rules =  (List<Rule>) params.get("entity");
			}
			keyword = params.get("keyword").toString();
			String page = params.get("pages").toString();
			if (StringUtils.isNotBlank(page)) {
				pages = Integer.valueOf(page);
			}
		}
		if (rules == null) {
			return "信息采集失败！站点不存在！";
		}
		
		for (Rule rule : rules) {
			if(rule.getId()==null){
				continue;
			}
			//格式化URL
			String[] Urls = rulePR.scanUrlsHandle(rule,keyword,pages);
			
			Site site = Site.me().setDomain(rule.getDomains()).setSleepTime(3000).setRetryTimes(3);
			
			List<RuleDetail> ruleDetails = rulePR.getRuleDetails(rule.getId());
			
			ResultItemsCollectorPipeline resultItemsCollectorPipeline = new ResultItemsCollectorPipeline();
			
			//根据页面类型选择不同的采集器
			if (rule.getGrabType()==0) {
				//根据页面类型选择不同的采集器
				if (rule.getPageType()==0) {
					Spider s = Spider.create(new HTMLProcessor(site, rule, ruleDetails));
					s.addUrl(Urls);
					s.thread(10);
					s.addPipeline(resultItemsCollectorPipeline);
					s.run();
				}else {
					Spider s = Spider.create(new JSProcessor(site, ruleDetails,rule));
					s.addUrl(Urls);
					s.thread(10);
					s.addPipeline(resultItemsCollectorPipeline);
					s.run();
				}
			}else{
				Spider s = Spider.create(new SinglePageHtmlProcessor(site, rule, ruleDetails));
				s.addUrl(Urls);
				s.thread(10);
				s.addPipeline(resultItemsCollectorPipeline);
				s.run();
			}
			
			//获取采集结果，进行数据持久化
			List<ResultItems> list = resultItemsCollectorPipeline.getCollected();
			for (ResultItems resultItems : list) {
				if (resultItems.get("infos") instanceof List) {
					List<Infos> infosList = resultItems.get("infos");
					for (Infos infos : infosList) {
						if (infos!=null && !this.isRepetitionInfos(infos.getField1(),rule.getCreateUserId())) {
							infos.setCreateUserId(rule.getCreateUserId());
							this.jObHibernateDao.save(infos);
						}
					}
				}else {
					final Infos infos = resultItems.get("infos");
					if (infos!=null && !this.isRepetitionInfos(infos.getField1(),rule.getCreateUserId())) {
						infos.setCreateUserId(rule.getCreateUserId());
						this.jObHibernateDao.save(infos);
					}
				}
			}
			
		}
		
		return "采集完成！";
	}
	
	/**
	 * 对采集的数据进行去重操作
	 * @param title
	 * @return
	 */
	public boolean isRepetitionInfos(String title,String createUserId){
		
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Infos.class);
		
		int count = 0;
		if (StringUtils.isNotBlank(title)) {
			Disjunction disjunction = Restrictions.disjunction();
			
			disjunction.add(Restrictions.eq("field1", title));
			disjunction.add(Restrictions.eq("field2", title));
			disjunction.add(Restrictions.eq("field3", title));
			disjunction.add(Restrictions.eq("field4", title));
			disjunction.add(Restrictions.eq("field5", title));
			disjunction.add(Restrictions.eq("field6", title));
			disjunction.add(Restrictions.eq("field7", title));
			disjunction.add(Restrictions.eq("field8", title));
			
			detachedCriteria.add(disjunction);
			detachedCriteria.add(Restrictions.eq("createUserId", createUserId));
			count = this.commonHibernateDao.queryCount(detachedCriteria);
		}
		
		if (count>0) {
			return true;
		}else {
			return false;
		}
		
	}

}
